Report per-agent and per-engine token usage from a sealed run - #4
Merged
Conversation
… anonymous shards
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A sealed run now reports what it cost.
observederives per-agent and per-engine token usage from the exported Daimon ledger atraw/daimon/usage.jsonl, surfaced asusage[]andusage_summaryon the observe report.No lifecycle-contract change was needed. Simfile already reads exported raw artifacts directly — this follows exactly how
memoryBanks.tsderives per-bank counts fromraw/mneme/<bank>/. The pinned 43-row capability contract is untouched, so this needs no coordinated Spawnfile release.Boundaries hold: no Spawnfile import, own zod schema with
.strict()so an unknown key is rejected rather than stripped, file reads only, nothing selects or wakes cognition.The lower-bound guarantee is structural
usage_summary.lower_boundisz.literal(true), notz.boolean(). A report asserting these counts are exact is not representable insimfile.observe.v1— there is a test that alower_bound: falsereport fails to parse.This matters because the qualification is load-bearing. An all-zero usage block means unknown, not free; AGY reports no cost field at all; codex is unmetered by design.
unknown_turnscarries the producer'scomplete: falsesignal per agent and in aggregate. A report that quietly presented these as exact would recreate the exact failure this feature exists to prevent — a dead subscription that looked like zero cost.Absent is not zero
collectUsagereturnsundefinedwhen neither ledger generation exists, and the report omitsusageentirely — followingworldGrants.ts, which already establishes that convention and documents it. A present-but-empty ledger aggregates to[], an observed zero. The two are distinguishable.Both rotation generations are read, oldest first. Engine attribution comes from an agent's earliest record, so an agent that switches engine mid-run reports the one it started on.
Verification
1687 tests passing.
tsc --noEmitclean on bothtsconfig.jsonandtsconfig.web.json.Four mutations, each confirmed against the named subtest it kills rather than the failure count: reversing generation order, treating an absent ledger as empty, relaxing
lower_boundto a boolean, and dropping the incomplete-turn signal.Related
Depends on the export side in noopolis/spawnfile#7, which carries both ledger generations into exported run artifacts.